package com.cloudbench.util;

import static android.content.Context.CONNECTIVITY_SERVICE;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Collections;
import java.util.List;

import android.annotation.SuppressLint;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import ch.boye.httpclientandroidlib.conn.util.InetAddressUtils;

/**
 *
 * @author : justin@zerodesktop.com
 * @version : 1.0.0
 * @data : 2011. 10. 16.
 *
 */
public class NetworkUtil {

	/**
	 * 
	 * @param ctx
	 * @return
	 */
	static ConnectivityManager getConnectivityManager(Context ctx) {
		if(ctx == null)
			return null;
		
		return (ConnectivityManager) ctx.getSystemService(CONNECTIVITY_SERVICE);
	}
	
	/**
	 * Check netowork is reachable.
	 * 
	 * @param ctx
	 * @return
	 */
	public static boolean isAvailable(Context ctx) {
		
		if(checkConnectionType(ctx) >= 0)
			return true;
		
		
		return false;
		
		/*
		ConnectivityManager cm = getConnectivityManager(ctx);
		if (cm == null)
			return false;

		NetworkInfo nInfo = cm.getActiveNetworkInfo();
		if(nInfo != null && nInfo.isAvailable() && nInfo.isConnected())
			return true;
				
		return false;
		*/
	}

	
	public static int checkConnectionType(Context ctx) {
	    final ConnectivityManager conMgr = getConnectivityManager(ctx);
	    if(conMgr == null)
	    	return -1;
	    
	    final NetworkInfo activeNetInfo = conMgr.getActiveNetworkInfo();
	    if (activeNetInfo != null && activeNetInfo.isAvailable() && activeNetInfo.isConnected()) {
	        int type = activeNetInfo.getType();
	        if (type == ConnectivityManager.TYPE_MOBILE || type == ConnectivityManager.TYPE_MOBILE_DUN
	                || type == ConnectivityManager.TYPE_MOBILE_HIPRI || type == ConnectivityManager.TYPE_MOBILE_MMS
	                || type == ConnectivityManager.TYPE_MOBILE_SUPL || type == ConnectivityManager.TYPE_WIMAX) {
	            return ConnectivityManager.TYPE_MOBILE;
	        } else if (type == ConnectivityManager.TYPE_WIFI) {
	            return ConnectivityManager.TYPE_WIFI;
	        } else {
	            // Unknown connection type, so to be safe say mobile
	            return ConnectivityManager.TYPE_MOBILE;
	        }
	    } else {
	        // return not connected
	        return -1;
	    }
	}	
	
	/**
	 * Check wifi is reachable
	 * 
	 * @param ctx
	 * @return
	 */
	public static boolean isWifiAvailable(Context ctx) {
		ConnectivityManager cm = getConnectivityManager(ctx);
		if (cm == null)
			return false;
		
		NetworkInfo nInfo = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
		if(nInfo == null) 
			return false;
		
		return nInfo.isConnectedOrConnecting();
	}
	
	/**
	 * Check mobile network is reachable 
	 * 
	 * @param ctx
	 * @return
	 */
	public static boolean isMobileAvailable(Context ctx) {
		ConnectivityManager cm = getConnectivityManager(ctx);
		if (cm == null)
			return false;
		
		NetworkInfo nInfo = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
		if(nInfo == null) 
			return false;
		
		return nInfo.isConnectedOrConnecting();
	}
	
	/**
	 * 
	 * @param useIPv4
	 * @return
	 */
    @SuppressLint("DefaultLocale")
	public static String getIPAddress(boolean useIPv4) {
        try {
            List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface intf : interfaces) {
                List<InetAddress> addrs = Collections.list(intf.getInetAddresses());
                for (InetAddress addr : addrs) {
                    if (!addr.isLoopbackAddress()) {
                        String sAddr = addr.getHostAddress().toUpperCase();
                        boolean isIPv4 = InetAddressUtils.isIPv4Address(sAddr); 
                        if (useIPv4) {
                            if (isIPv4) 
                                return sAddr;
                        } else {
                            if (!isIPv4) {
                                int delim = sAddr.indexOf('%'); // drop ip6 port suffix
                                return delim<0 ? sAddr : sAddr.substring(0, delim);
                            }
                        }
                    }
                }
            }
        } catch (Exception ex) { } // for now eat exceptions
        return "";
    }		
		
}
